Getting Backtrace

How can I trap the backtrace of errors?

When I do this:

  • real r = (4.0)/(0.0)   // illegal divide by zero

I want this, as printed in the DXL output pane:

  • -R-E- DXL: <Line:5> incorrect argument for operator (/), (0)
  • Backtrace:
  •          <Line:10>
  • -I- DXL: execution halted

But when I trap with noError/lastError I only get this:

  • -R-E- DXL: <Line:5> incorrect argument for operator (/), (0)

-Louie

I don't think I can mess with Error Logging in production environment.


llandale - Fri Jun 05 10:51:51 EDT 2015

Re: Getting Backtrace
Mathias Mamsch - Sat Jun 06 14:47:45 EDT 2015

Just to get this straight:

eval_ "\n\nreal r=((1.0) / (0.0))" // error on line 3
print "Hello"

This yields:

-R-E- DXL: <Line:3> inorrect argument for operator (/), (0)
-I- DXL: execution haltet
Hello

So execution continues, DXL error is dumped to output. Now you want to catch the error with noError() / lastError(). You cannot do it from the outside: 

noError()
eval_ "\n\nreal r=((1.0) / (0.0))" // error on line 3
string msg=lastError()
print "Hello:" msg "\n"

This will print the "Hello:" after the message, since the noerror has no effect inside the eval_ context. So you will need to put the noError() / lastError inside:

eval_ "noError()\n\nreal r=((1.0) / (0.0))\nstring msg=lastError(); print msg" // error on line 3
print "\nHello!"

Of course you only get "error on line 3" since the DXL produces its own traceback, but the DXL execution continues afterwards. The child context will not end the parent context. So I kind do not get what you are asking for.

You need to be careful with Sodius DXL editor in this case. You might trick the execution engine into giving you a traceback with an extra entry, although as far as I know this should not happen. You also should be aware that the output of the Sodius DXL Editor console is not what the DXL outputs - The DXL editor will do path replacements, which can lead in some cases to confusing output.

You can always get the current traceback using dxlHere() ... However the child context does not know of its parent context. If you want a "combined" traceback you would have to

a) catch the error inside the eval_

b) hand the error and traceback to the parent context

c) call dxlHere() on the parent and append this to (removing the first line) to the traceback of the eval ...

I am not sure this answers the question ... Anyway, Regards, Mathias

Re: Getting Backtrace
Wolfgang Uhr - Mon Jun 08 08:05:18 EDT 2015

Hi Louie

Use the following code:

----

void myErrorDemo() {

 noError();

 real r = (4.0)/(0.0) // illegal divide by zero

 string sErrorMessage = lastError();

 if (sErrorMessage != "") {

  print "Error: " sErrorMessage "\n";

  print dxlHere(); // This is line 7

 }

}

myErrorDemo();  // This ist line 11

----

And you will get the following result

Error: -R-E- DXL: <Line:3> incorrect argument for operator (/), (0)

<Line:7>

<Line:7>

<Line:11>

[progress] Done.

 

Best regards

Wolfgang

Re: Getting Backtrace
Mathias Mamsch - Mon Jun 08 18:39:29 EDT 2015

Mathias Mamsch - Sat Jun 06 14:47:45 EDT 2015

Just to get this straight:

eval_ "\n\nreal r=((1.0) / (0.0))" // error on line 3
print "Hello"

This yields:

-R-E- DXL: <Line:3> inorrect argument for operator (/), (0)
-I- DXL: execution haltet
Hello

So execution continues, DXL error is dumped to output. Now you want to catch the error with noError() / lastError(). You cannot do it from the outside: 

noError()
eval_ "\n\nreal r=((1.0) / (0.0))" // error on line 3
string msg=lastError()
print "Hello:" msg "\n"

This will print the "Hello:" after the message, since the noerror has no effect inside the eval_ context. So you will need to put the noError() / lastError inside:

eval_ "noError()\n\nreal r=((1.0) / (0.0))\nstring msg=lastError(); print msg" // error on line 3
print "\nHello!"

Of course you only get "error on line 3" since the DXL produces its own traceback, but the DXL execution continues afterwards. The child context will not end the parent context. So I kind do not get what you are asking for.

You need to be careful with Sodius DXL editor in this case. You might trick the execution engine into giving you a traceback with an extra entry, although as far as I know this should not happen. You also should be aware that the output of the Sodius DXL Editor console is not what the DXL outputs - The DXL editor will do path replacements, which can lead in some cases to confusing output.

You can always get the current traceback using dxlHere() ... However the child context does not know of its parent context. If you want a "combined" traceback you would have to

a) catch the error inside the eval_

b) hand the error and traceback to the parent context

c) call dxlHere() on the parent and append this to (removing the first line) to the traceback of the eval ...

I am not sure this answers the question ... Anyway, Regards, Mathias

I could have sworn I read "eval_" :-) Never mind my answer! Regards, Mathiass

Re: Getting Backtrace
llandale - Sat Jun 27 15:18:15 EDT 2015

Wolfgang Uhr - Mon Jun 08 08:05:18 EDT 2015

Hi Louie

Use the following code:

----

void myErrorDemo() {

 noError();

 real r = (4.0)/(0.0) // illegal divide by zero

 string sErrorMessage = lastError();

 if (sErrorMessage != "") {

  print "Error: " sErrorMessage "\n";

  print dxlHere(); // This is line 7

 }

}

myErrorDemo();  // This ist line 11

----

And you will get the following result

Error: -R-E- DXL: <Line:3> incorrect argument for operator (/), (0)

<Line:7>

<Line:7>

<Line:11>

[progress] Done.

 

Best regards

Wolfgang

Sorry about late reply.  This seems to work thanks.  Did they change "dxlHere" as my nagging memory of several years ago said it didn't work; it only returned the current line of code.

I've got a massive library and in this case function "fBaseName()" triggers a sequence of functions.  Deep down I issued a print dxlHere.

Test Code:

#include <Includes\Lib-General\Lib-Incs_Common.inc>


string EvalCode = "
#include <Includes/Lib-General/Lib-EvalStubs.inc>
#include <Includes/Lib-General/Lib-Incs_Common.inc>
string s = fBaseName(\"/ddd/ddd/xx\")
" // end string EvalCode

void RunEval()
{
 print "in RunEval()...\n"
 eval_(EvalCode)
}


void RunStraight()
{ print "in RunStraight()...\n"
 string s = fBaseName("/ddd/ddd/xx")
}

RunStraight()
RunEval()

Results:

in RunStraight()...
 fGetOffsetLast: dxlHere:
<Includes/Lib-General/Lib-Variables.inc:1003>
<Includes/Lib-General/Lib-Variables.inc:1028>
<Includes/Lib-General/Lib-Variables.inc:2344>
<Includes/Lib-General/Lib-Variables.inc:2343>
<Includes/Lib-General/Lib-Variables.inc:2394>
<Line:19>  // << trace back to function "RunStraight()"
<Line:22>
in RunEval()...
 fGetOffsetLast: dxlHere:
<Includes/Lib-General/Lib-Variables.inc:1003>
<Includes/Lib-General/Lib-Variables.inc:1028>
<Includes/Lib-General/Lib-Variables.inc:2344>
<Includes/Lib-General/Lib-Variables.inc:2343>
<Includes/Lib-General/Lib-Variables.inc:2394>
<Line:4>  // <<-- notice no trace back to function "RunEval()"

So it appears that if I want a trace back from an origin inside an eval_, I'll need to issue a 2nd dxlHere from the function that calls eval_.  Or if I were MM I'd override the native "eval_" and do it there.

-Louie